package program.conditions;

import be.kuleuven.cs.som.annotate.*;
import item.*;
/**
 * A class concerning or-conditions: (or(condition)(condition)).
 *
 * @invar	The first condition of each or-condition must be valid.
 *                      | canHaveAsCondition(getFirstCondition())
 * @invar       The second condition of each or-condition must be valid.
 *                      | canHaveAsCondition(getSecondCondition())
 *
 */ public class Or extends Conditions {
	 private final Conditions firstCondition;
	 private final Conditions secondCondition;
	 
	 /**
	  * Initialise this new or-condition with a line number and two conditions.
	  *
	  * @param	firstCondition
	  *           	The first condition to be evaluated.
	  * @param	secondCondition
	  *               The second condition to be evaluated.
	  * @pre	The given first condition should be valid.
	  *               | canHaveAsCondition(firstCondition)
	  * @pre    The given second condition should be valid.
	  *               | canHaveAsCondition(secondCondition)
	  * @post	The first condition of this or-command is set to the given condition.
	  *               | new.getFirstCondition() == firstCondition
	  * @post   The second condition of this or-command is set to the given condition.
	  *               | new.getSecondCondition() == secondCondition
	  */
	 public Or(int lineNb, Conditions firstCondition, Conditions secondCondition) {
		 super(lineNb);
		 assert(canHaveAsConditions(firstCondition));
		 assert(canHaveAsConditions(secondCondition));
		 this.firstCondition = firstCondition;
		 this.secondCondition = secondCondition;
	 }
	 
	 /**
	  * Returns the first condition to be evaluated.
	  */
	 @Basic @Raw @Immutable
	 public Conditions getFirstCondition() {
		 return firstCondition;
	 }
	 
	 /**
	  * Returns the second condition to be evaluated.
	  */
	 @Basic @Raw @Immutable
	 public Conditions getSecondCondition() {
		 return secondCondition;
	 }
	 
	 /**
	  * Checks whether the given condition is a valid one for an or-condition.
	  *
	  * @param	condition
	  *      		The condition to check for whether it is a valid one.
	  * @return	
	  *           | result == ( condition != null)
	  */
	 @Raw
	 public boolean canHaveAsConditions(Conditions conditions) {
		 return ( conditions != null );
	 }
	 
	 /**
	  * Evaluates this condition for a given robot.
	  *
	  * @return
	  *           | result == ( super.evaluate(robot) &&( getFirstCondition().evaluate(robot) ||
	  *           |		getSecondCondition().evaluate(robot) ) )
	  */
	 @Override
	 public boolean evaluate(Robot robot) {
		 super.evaluate(robot);
		 return ( super.evaluate(robot) && ( getFirstCondition().evaluate(robot) ||
				 getSecondCondition().evaluate(robot) ) );
	 }
	 
	 /**
	  * Returns a textual representation of this or-condition,
	  * formatted in accordance with its position in the program.
	  *
	  * @return	
	  *         | result == getIndentation(indentationLevel) + "(or\n" +
	  *         |     getFirstCondition().prettyFormat(indentationLevel+1) + "\n" +
	  *         |     getSecondCondition().prettyFormat(indentationLevel+1) + "\n)"
	  */
	 @Override
	 public String prettyFormat(int indentationLevel) {
		 return getIndentation(indentationLevel) + "(or\n" +
				 getFirstCondition().prettyFormat(indentationLevel+1) + "\n" +
				 getSecondCondition().prettyFormat(indentationLevel+1) + "\n)";
	 }
 } 
